﻿using System;
using System.Collections.Generic;
using System.Linq;
//using System.Threading;
using System.Web;
using DrillOnline.Hubs;
using Microsoft.AspNet.SignalR;

namespace DrillOnline.Services.Scenarios
{
    public class Timeline
    {
        public class TickerEventArgs : EventArgs
        {
            public Timeline Ticker { get; set; }
            public double LastOffset { get; set; }
            public double NewOffset { get; set; }
        }
        protected int _TickerInterval = 1000;

        /// <summary>
        /// 剧情刷新时间，现实时间，单位毫秒。默认1000
        /// </summary>
        public int Config_TickerInterval
        {
            get { return _TickerInterval; }
            set
            {
                _TickerInterval = value;
                if (null != Timer)
                {
                    Timer.Interval = _TickerInterval;
                }
                if (_TickerInterval < 100) throw new ArgumentOutOfRangeException("Warnning: TickerInterval less then 100");
            }
        }
        /// <summary>
        ///剧情时间和真实时间的比例，如60，表示1秒代表1分钟。
        /// </summary>
        public int Config_PlayingTimeRate { get; set; }

        private System.Timers.Timer Timer;

        public DateTime PlayingStartTime;
        public DateTime StoryBaseTime;


        public double PlayingOffset;
        public int PlayingSceneIndex { get; set; }

        //public DateTime _RealCurrentTime;
        public DateTime RealCurrentTime
        {
            get { return DateTime.Now; }
        }
        //public DateTime _StoryCurrentTime;
        public DateTime StoryCurrentTime
        {
            get { return StoryBaseTime.AddSeconds(PlayingOffset); }
        }
        public void JumpTo(DateTime t)
        {
            var sec = (t - StoryBaseTime).TotalSeconds;
            JumpTo((int)sec);
        }
        public void JumpTo(double offset)
        {
            PlayingOffset = offset;
        }
        //public DateTime OffsetToStoryTime(int offset) {
        //    return StoryStartTime.AddSeconds(offset);
        //}
        //public int StoryTimeToOffset(DateTime dt) {
        //    return (int)((dt - StoryStartTime).TotalSeconds);
        //}

        /// <summary>
        /// stop,pause,playing=0,1,2
        /// </summary>
        public int Status { get { return _Status; } protected set { if (_Status != value) { _Status = value; if (null != OnStatusChange) OnStatusChange(this, null); } } }
        int _Status;
        public event EventHandler<TickerEventArgs> OnElapsed;
        public event EventHandler OnStatusChange;

        public void Start()
        {
            if (Status == 0)
            {
                PlayingStartTime = DateTime.Now;
                PlayingOffset = 0;
                PlayingSceneIndex = 0;
                if (null != Timer) Timer.Dispose();
                Timer = new System.Timers.Timer(Config_TickerInterval);
                Timer.Elapsed += Time_Elapsed;
                Timer.Start();
                Status = 2;
            }
            else if (Status == 1)
            {
                if (Timer != null) Timer.Start();
                Status = 2;
            }
        }

        void Time_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //var ts = e.SignalTime - PlayingStartTime;
            var lastplayingsecoffset = PlayingOffset;
            PlayingOffset += (Timer.Interval * Config_PlayingTimeRate / 1000d);//(int)(ts.TotalSeconds * Config_PlayingTimeRate);
            if (null != OnElapsed)
            {
                OnElapsed(this, new TickerEventArgs() { Ticker = this, LastOffset = lastplayingsecoffset, NewOffset = PlayingOffset });
            }
        }
        public void Pause()
        {
            if (Timer != null) Timer.Stop();
            Status = 1;
        }
        public void Stop()
        {
            if(Timer!=null) Timer.Stop();
            Status = 0;
        }
        public void Dispose()
        {
            try
            {
                Stop();
                Timer.Dispose();
            }
            catch { }
        }
        public Timeline()
        {

        }
    }
}